﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ProcedureControlApi.DbContext;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;

namespace ProcedureControlApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HeartbeatController : ControllerBase
    {
        public static object _lock = new object();
        public static ConcurrentDictionary<string, MyTimer> serverTimer { get; set; } = new ConcurrentDictionary<string, MyTimer>();
        /// <summary>
        /// 处理第三方程序心跳
        /// </summary>
        /// <param name="serverName"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("{serverName}")]
        public string HeartbeatHandle(string serverName)
        {
            lock (_lock)
            {
                using (var db = new ProcedureServerContext())
                {
                    var data = db.Servers.FirstOrDefault(e => e.Name == serverName);
                    if (data == null || data.Id <= 0)
                    {
                        return "error";
                    }
                    data.IsOnline = true;
                    data.LastHeartbeatTime = DateTime.Now;
                    db.Servers.Update(data);
                    db.SaveChanges();
                }
                var result = serverTimer.TryGetValue(serverName, out MyTimer timer);
                if (result)
                {
                    //存在
                    timer.Close();
                    timer.Start();
                }
                else
                {
                    //不存在
                    var myTimer = new MyTimer
                    {
                        Interval = 1000 * 60 * 10,//10分钟
                        Enabled = true,
                        AutoReset = false,
                        ServerName = serverName
                    };
                    myTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
                    myTimer.Start();
                    serverTimer.TryAdd(serverName, myTimer);

                }
                return "ok";
            }
        }

        private async void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            MyTimer timer = (MyTimer)source;
            using (var db = new ProcedureServerContext())
            {
                var data = db.Servers.Where(e => e.Name == timer.ServerName).FirstOrDefault();
                if (data != null && data.Id > 0)
                {
                    data.IsOnline = false;
                    //data.LastHeartbeatTime = DateTime.Now;
                    db.Servers.Update(data);
                    await db.SaveChangesAsync();
                }
            }
        }
    }



    /// <summary>
    /// 自定义定时器
    /// </summary>
    public class MyTimer : System.Timers.Timer
    {
        public string ServerName { get; set; }
    }
}
